import express = require('express');
import crypto = require('crypto');
import superagent = require('superagent');
import cheerio = require('cheerio');
import url = require('url');
import async = require('async');

interface DemoResponse extends Express.Response{
    send(content:any):void;
}

interface DemoRequest extends Express.Request{
    query:{
        q:string;
    }
}

class DemoController{
    constructor(private app:express.Express){
        this.app.get('/',this.get);
        this.app.get('/cnode',this.getCnode);
        this.app.get('/note',this.getNote);
        this.app.get('/async',this.getAsync);
        this.app.listen(3000,() =>{
            console.log('app is listening at port 3000');
        });
    }

    get(req:DemoRequest, res:DemoResponse):void{
        var q = req.query.q;
        var md5 = crypto.createHash('md5');
        var pwd = md5.update(q).digest('base64');
        res.send(pwd);
    }

    getCnode(req:Express.Request, res:DemoResponse):void{
        let items = new Array<{title:string,href:string}>();
        superagent.get('https://cnodejs.org/')
        .end((err,sres) =>
        {
            if(err){
                console.log(err);
            }
            let $ = cheerio.load(sres.text);
            $('#topic_list .topic_title').each((idx,ele) =>{
                let $ele = $(ele);
                items.push({
                    title:$ele.attr('title'),
                    href:$ele.attr('href')
                })
            });
        });

        res.send(items);
    }

    getNote(req:Express.Request, res:DemoResponse):void{
        let topicUrl = new Array<string>();

        superagent.get('https://cnodejs.org/')
        .end((err,res) =>{
            if(err){
                console.log(err);
            }

            let $ = cheerio.load(res.text);
            $('#topic_list .topic_title').each((idx,ele) => {
                let $ele = $(ele);
                let href = url.resolve('https://cnodejs.org/',$ele.attr('href'));
                topicUrl.push(href);
            });
        });

        res.send(topicUrl);
    }

    getAsync(req:Express.Request, res:DemoResponse):void{
        var councurrencyCount = 0;
        let fetchUrl = function(url:string, callback:(err:any,callback:string) => void):void {
            let delay = parseInt(((Math.random() * 10000000) % 2000).toString(),10);
            councurrencyCount++;
            console.log('现在并发数是'+ councurrencyCount + '，正在抓取的是' + url +'耗时' + delay + '毫秒');
            setTimeout(function() {
                councurrencyCount--;
                callback(null,url + 'html content');
            }, delay);
        };

        var urls:Array<string> = new Array<string>();
        for(let i = 0;i < 30;i++)
        {
            urls.push("http://datasource_" + i);
        }

        async.mapLimit<string,string>(urls,5,function(url,callback):void{
            fetchUrl(url,callback);
        },(err,results) => {
            console.log('funal:');
            console.log(results); 
        });

        res.send("ok");
    }
}

function main(){
    new DemoController(express());
}

main();